﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		PluginRepository.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 // 
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System;
using System.Collections.Generic;
using System.Linq;
using Dexter.Domain.Model;
using Dexter.Domain.Results;
using Dexter.Logger.Contracts;
using Dexter.Repository.NHibernate.Queries;
using NHibernate;
using ISessionFactory = Dexter.Repository.NHibernate.SessionFactory.ISessionFactory;

namespace Dexter.Repository.NHibernate.Repositories {
	/// <summary>
	/// 	Implementation of <see cref = "IPluginRepository" />.
	/// </summary>
	public class PluginRepository : RepositoryBase <Plugin> , IPluginRepository {
		/// <summary>
		/// 	Initializes a new instance of the <see cref = "PluginRepository" /> class.
		/// </summary>
		/// <param name = "sessionFactory">The session factory.</param>
		/// <param name = "logger">The logger.</param>
		public PluginRepository ( ISessionFactory sessionFactory , ILogger logger ) : base ( sessionFactory , logger ) {}

		public IList<Plugin> GetAllPlugins() {
			return Session.QueryOver<Plugin>().List();
		}

		public Plugin GetPluginByIdentifier(Guid identifier) {
			return Session.GetNamedQuery(KnownQueries.PluginRepository.GetPluginByIdentifier)
				.SetParameter("identifier", identifier)
				.UniqueResult<Plugin>();
		}

		public void SaveOrUpdate(Plugin item) {
			if(item == null)
				throw new ArgumentNullException("item");

			if(item.IsTransient)
				item.ValidateForSave();
			else
				item.ValidateForUpdate();
			
			Session.SaveOrUpdate(item);
		}

		public void Delete(Plugin item) {
			if (item == null)
				throw new ArgumentNullException("item");

			item.ValidateForDelete();

			base.Remove(item);
		}

		public void SaveOrUpdateData(PluginData data) {
			if (data == null)
				throw new ArgumentNullException("data");

			if (data.IsTransient)
				data.ValidateForSave();
			else
				data.ValidateForUpdate();

			Session.SaveOrUpdate(data);
		}

		public PluginData RetrieveDataFromKey(Plugin plugin, string key) {
			return Session.GetNamedQuery(KnownQueries.PluginRepository.RetrieveDataFromKey)
				.SetParameter("pluginId", plugin.Id)
				.SetParameter("key", key)
				.UniqueResult<PluginData>();
		}

		public IPagedResult<PluginData> RetrieveDataFromCreationDate(Plugin plugin, DateTime creationDate, int pageSize, int pageIndex) {
			var startDate = new DateTime(creationDate.Year, creationDate.Month, creationDate.Day,0,0,0);
			var endDate = new DateTime(creationDate.Year, creationDate.Month, creationDate.Day, 23, 59, 59);
			
			return RetrieveDataForSpecifiedDateRange(plugin, startDate, endDate, pageSize, pageIndex);
		}

		public IPagedResult<PluginData> RetrieveDataForSpecifiedDateRange(Plugin plugin, DateTime startDate, DateTime endDate, int pageSize, int pageIndex) {
			IFutureValue<long> total = Session.GetNamedQuery(KnownQueries.PluginRepository.RetrieveDataForSpecifiedDateRangeCount)
				.SetParameter("pluginId", plugin.Id)
				.SetParameter("startDate", startDate)
				.SetParameter("endDate", endDate)
				.FutureValue<long>();

			IEnumerable<PluginData> result = Session.GetNamedQuery(KnownQueries.PluginRepository.RetrieveDataForSpecifiedDateRange)
				.SetParameter("pluginId", plugin.Id)
				.SetParameter("startDate", startDate)
				.SetParameter("endDate", endDate)
				.SetFirstResult(pageIndex * pageSize)
				.SetMaxResults(pageSize)
				.SetReadOnly(true)
				.Future<PluginData>();

			return new PagedResult<PluginData>(pageIndex, pageSize, result.ToList(), total.Value);
		}
	}
}
